using UnityEditor;
using UnityEngine;

[UnityEditor.CanEditMultipleObjects]
[UnityEditor.CustomEditor(typeof(AudioStudio.EmitterSound))]

public class EmitterSoundInspector : Editor
{
    AudioStudio.EmitterSound component;
    bool showAttSphere = false;

    private int curPointIndex = -1;
    private static UnityEngine.Color SPHERE_COLOR = new UnityEngine.Color(1.0f, 0.0f, 0.0f, 0.1f);

    public static bool populateSoundBank = true;

    void OnEnable()
    {
        //populateSoundBank = true;
        component = target as AudioStudio.EmitterSound;
        UnityEditor.EditorApplication.update += PopulateMaxAttenuation;
    }

    private void OnDisable()
    {
        UnityEditor.EditorApplication.update -= PopulateMaxAttenuation;
        populateSoundBank = true;
    }

    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        EditorGUILayout.LabelField("Event:");
        EditorGUILayout.PropertyField(serializedObject.FindProperty("audioevent"), GUIContent.none);
        using (new UnityEngine.GUILayout.HorizontalScope())
        {
            if (UnityEngine.GUILayout.Button("Add Point"))
                component.multiPositionArray.Add(component.transform.InverseTransformPoint(new Vector3(component.transform.position.x+1,component.transform.position.y,component.transform.position.z+1)));
        
            if (curPointIndex >= 0 && UnityEngine.GUILayout.Button("Delete Point"))
            {
                component.multiPositionArray.RemoveAt(curPointIndex);
                curPointIndex = component.multiPositionArray.Count - 1;
            }
        }
        EditorGUILayout.LabelField("Positions:");
        var list = serializedObject.FindProperty("multiPositionArray");
        if (list != null)
        {
            for (int i = 0; i < list.arraySize; i++)
            {
                EditorGUILayout.BeginHorizontal();
                EditorGUILayout.LabelField("Point_"+i);
                EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i), GUIContent.none);

                EditorGUILayout.EndHorizontal();
                EditorGUILayout.Separator();
            }
        }
        EditorGUILayout.LabelField("Positions Type:");
        EditorGUILayout.PropertyField(serializedObject.FindProperty("positiontype"), GUIContent.none);
        serializedObject.ApplyModifiedProperties();
    }

    private void OnSceneGUI()
    {
        RenderAttenuationSpheres();

        var someHashCode = GetHashCode();

        for (var i = 0; i < component.multiPositionArray.Count; i++)
        {
            var pos = component.multiPositionArray[i];

            UnityEditor.Handles.Label(pos, "Point_" + i);

            var handleSize = UnityEditor.HandleUtility.GetHandleSize(pos);

            // Get the needed data before the handle
            var controlIDBeforeHandle = UnityEngine.GUIUtility.GetControlID(someHashCode, UnityEngine.FocusType.Passive);
            var isEventUsedBeforeHandle = UnityEngine.Event.current.type == UnityEngine.EventType.Used;

            UnityEditor.Handles.color = UnityEngine.Color.green;
#if UNITY_5_6_OR_NEWER
            UnityEditor.Handles.CapFunction capFunc = UnityEditor.Handles.SphereHandleCap;
#else
			UnityEditor.Handles.DrawCapFunction capFunc = UnityEditor.Handles.SphereCap;
#endif
            UnityEditor.Handles.ScaleValueHandle(0, pos, UnityEngine.Quaternion.identity, handleSize, capFunc, 0);

            if (curPointIndex == i)
                pos = UnityEditor.Handles.PositionHandle(pos, UnityEngine.Quaternion.identity);

            // Get the needed data after the handle
            var controlIDAfterHandle = UnityEngine.GUIUtility.GetControlID(someHashCode, UnityEngine.FocusType.Passive);
            var isEventUsedByHandle = !isEventUsedBeforeHandle && UnityEngine.Event.current.type == UnityEngine.EventType.Used;

            if (controlIDBeforeHandle < UnityEngine.GUIUtility.hotControl &&
                UnityEngine.GUIUtility.hotControl < controlIDAfterHandle || isEventUsedByHandle)
                curPointIndex = i;

            component.multiPositionArray[i] = pos;
        }
    }

    public void RenderAttenuationSpheres()
    {
        UnityEditor.Handles.matrix = component.transform.localToWorldMatrix;
        float radius = 0;
        if (component.audioevent != null)
            radius = AkWwiseProjectInfo.GetData().GetEventMaxAttenuation(component.audioevent.Id);

        for (var i = 0; i < component.multiPositionArray.Count; i++)
            DrawSphere(component.multiPositionArray[i], radius);
    }

    private void DrawSphere(UnityEngine.Vector3 in_position, float in_radius)
    {
        UnityEditor.Handles.color = SPHERE_COLOR;

        if (UnityEngine.Vector3.SqrMagnitude(
                UnityEditor.SceneView.lastActiveSceneView.camera.transform.position - in_position) > in_radius * in_radius)
        {
#if UNITY_5_6_OR_NEWER
            UnityEditor.Handles.SphereHandleCap(0, in_position, UnityEngine.Quaternion.identity, in_radius * 2.0f,
                UnityEngine.EventType.Repaint);
#else
			UnityEditor.Handles.SphereCap(0, in_position, UnityEngine.Quaternion.identity, in_radius * 2.0f);
#endif
        }
        else
            DrawDiscs(UnityEngine.Vector3.up, UnityEngine.Vector3.down, 6, in_position, in_radius);
    }

    private void DrawDiscs(UnityEngine.Vector3 in_startNormal, UnityEngine.Vector3 in_endNormal, uint in_nbDiscs,
        UnityEngine.Vector3 in_position, float in_radius)
    {
        var f = 1.0f / in_nbDiscs;
        for (var i = 0; i < in_nbDiscs; i++)
        {
            UnityEditor.Handles.DrawWireDisc(in_position, UnityEngine.Vector3.Slerp(in_startNormal, in_endNormal, f * i),
                in_radius);
        }
    }

    public static void PopulateMaxAttenuation()
    {
        if (populateSoundBank)
        {
            AkWwiseXMLBuilder.Populate();
            populateSoundBank = false;
            UnityEditor.SceneView.RepaintAll();
        }
    }

}

